﻿using Core.Container;
using Core.Interface;
using Core.Log;
using Prism.Ioc;
using ProcessControl.Model;
using ProcessControl.ViewModels;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace ProcessControl
{
    public class AutoProcess : IAutoProcess
    {
        CancellationTokenSource token;
        Step step;
        IContainerExtension Container;
        Container<ModBusDevice> container;
        //ModBusDevice modBusDevice;
        List<Task> listTask = new List<Task>();      
        ManualResetEvent manual;
        Notify notifyErr, notifyAuto, notifyIni;
        DisplayDataViewModel displayDataViewModel;
        YieldViewModel yieldViewModel;

        public AutoProcess()
        {
            manual = new ManualResetEvent(true);
            Container = ContainerLocator.Current;
            container = Container.Resolve<Container<ModBusDevice>>("ModBusDevice");
            displayDataViewModel= Container.Resolve<DisplayDataViewModel>();
            yieldViewModel=Container.Resolve<YieldViewModel>();    

            //modBusDevice = container.Get("A");
            notifyErr = NotifyCollect.NotifyContainer["Error"];
            notifyAuto = NotifyCollect.NotifyContainer["Auto"];
            notifyIni= NotifyCollect.NotifyContainer["Initialization"];
        }

        private void ExecuteMainTask()
        {
            while (!token.IsCancellationRequested)
            {
                if (ExecutionCondition())
                {
                    listTask.Add(Task.Run(Task1, token.Token));
                    listTask.Add(Task.Run(Task2, token.Token));
                    Task.WaitAll(listTask.ToArray(), 6000);//等待所有的线程完成后才会往下执行
                    notifyAuto.Add("两个线程执行完成------------");
                    Thread.Sleep(50);
                }
            }
        }
        private bool ExecutionCondition()
        {
            //modBusDevice.ReadRegister(0, out ushort value);
            //return (value == 11);
            return true;
        }

        private void Task1()
        {
            try
            {
                manual.WaitOne();
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "正在执行");
                Thread.Sleep(100);
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "正在执行");
                Thread.Sleep(160);
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "正在执行");


                yieldViewModel.NG++;
                yieldViewModel.Total++;

                notifyAuto.Add("任务1正在执行"+ Thread.CurrentThread.ManagedThreadId);
               
            }
            catch (Exception ex)
            {
                notifyErr.Add(ex.ToString());
            }
        }

        private void Task2()
        {
            try
            {
                manual.WaitOne();
                ProductionData productionData = new ProductionData();
                displayDataViewModel.DataShift(productionData);
                notifyAuto.Add("任务2正在执行" + Thread.CurrentThread.ManagedThreadId);
            }
            catch (Exception ex)
            {
                notifyErr.Add(ex.ToString());
            }
        }


        public void Init()
        {
            try
            {
                step = 0;
                token = new CancellationTokenSource();
                //if (modBusDevice.Connect())
                { notifyIni.Add("PLC连接成功!"); }
                notifyIni.Add("整机初始化完成");
            }
            catch (Exception ex)
            {
                notifyErr.Add(ex.ToString());
            }
        }

        public void Pause()
        {
            manual.Reset();
        }

        public void Continue()
        {
            manual.Set();
        }

        public void Start()
        {
            Task.Run(() => ExecuteMainTask());
        }

        public void Stop()
        {
            token.Cancel();
        }

        enum Step
        {
            取料1,
            移动,
            拍照,
            放料,
            放料1,
            放料2,
            放料3
        }
    }
}
